﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Security.Cryptography;
using System.Globalization;

namespace RandomStudent.Extends
{
    public class DiskCanvas : Canvas
    {
        private double angel;
        /// <summary>
        /// 角度
        /// </summary>
        public double Angel
        {
            get
            {
                return angel;
            }
            set { angel = value; }
        }
        private int count;
        /// <summary>
        /// 个数  角度和个数相*=360
        /// </summary>
        public int Count
        {
            get
            {
                count = App.TotleStudent;
                return count;
            }
            set { count = value; }
        }

        protected override void OnRender(System.Windows.Media.DrawingContext dc)
        {
            base.OnRender(dc);

            //
            //
            if (Angel < 0 || Angel > 360 || Count < 0)
            {
                return;
            }
            if (Count == 0)
            {
                Angel = 30;
                Count = 12;
            }
            //矫正 两个数字 
            Angel = (double)360 / (double)Count;
            //绘制圆盘饼图
            //==========================================
            for (int i = 0; i < Count; i++)
            {
                Path path = new Path();
                path.Stroke = System.Windows.Media.Brushes.Black;
                //渐变区间
                LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush();
                double random = new Random().NextDouble();
                myLinearGradientBrush.StartPoint = new Point(0, 0);
                myLinearGradientBrush.EndPoint = new Point(1, 1);
                myLinearGradientBrush.GradientStops.Add(
                    new GradientStop(GetRandomColor(), 0.0));
                myLinearGradientBrush.GradientStops.Add(
                    new GradientStop(GetRandomColor(), random));
                myLinearGradientBrush.GradientStops.Add(
                    new GradientStop(GetRandomColor(), 1 - random));
                myLinearGradientBrush.GradientStops.Add(
                    new GradientStop(GetRandomColor(), 1.0));

                path.Fill = myLinearGradientBrush;
                path.StrokeThickness = 1;
                path.HorizontalAlignment = HorizontalAlignment.Left;
                path.VerticalAlignment = VerticalAlignment.Center;

                //创建绘图容器
                PathGeometry pathGeometry = new PathGeometry();
                pathGeometry.Figures.Add(GetFigure(i * Angel, Angel));
                dc.DrawGeometry(path.Fill, new Pen(Brushes.Black, 1), pathGeometry);
                dc.DrawText(new FormattedText(App.Class7.Students[i].Num.ToString(),
                    CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface("Verdana"), 22, Brushes.Black),
                    (Point)(StrechHandOfPoint(ComputeCartesianCoodinate(i * Angel, Width / 2),1.1) - new Point(-Width / 2 + 10, -Width / 2 + 10)));
            }

        }
        private Point StrechHandOfPoint(Point point,double strechParam) {
            return new Point(point.X*strechParam,point.Y*strechParam);
        }

        public Color GetRandomColor()
        {
            return Color.FromArgb((byte)RollDice(266), (byte)RollDice(266), (byte)RollDice(266), (byte)(RollDice(266)));
        }

        public static int RollDice(int NumSides)
        {
            byte[] randomNumber = new byte[1];
            //PNGCryptoServiceProvider Gen = new PNGCryptoServiceProvider();
            System.Security.Cryptography.RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider();
            Gen.GetBytes(randomNumber);
            int rand = Convert.ToInt32(randomNumber[0]);
            return rand % NumSides;
        }


        double centerX = 100;
        double centerY = 100;
        /// <summary>
        /// 返回轮廓
        /// </summary>
        /// <param name="angleStart"></param>
        /// <param name="angleEnd"></param>
        /// <returns></returns>
        public PathFigure GetFigure(double angleStart, double angleEnd)
        {
            //圆形 
            centerX = Width / 2;
            centerY = Height / 2;
            double innerRadius = 30;
            double Radius = centerX;
            double angle = angleStart;
            double WedgeAngle = angleEnd;

            PathFigure pathFigure = new PathFigure();

            Point innerArcStartPoint = ComputeCartesianCoodinate(angle, innerRadius);
            Point innerArcEndPoint = ComputeCartesianCoodinate(angle + WedgeAngle, innerRadius);

            Point outerArcStartPoint = ComputeCartesianCoodinate(angle, Radius);
            Point outerArcEndPoint = ComputeCartesianCoodinate(angle + WedgeAngle, Radius);

            outerArcStartPoint.Offset(centerX, centerY);
            outerArcEndPoint.Offset(centerX, centerY);

            innerArcStartPoint.Offset(centerX, centerY);
            innerArcEndPoint.Offset(centerX, centerY);
            LineSegment lineToOuterArcStartPoint = new LineSegment(outerArcStartPoint, true);
            ArcSegment arcToOuterArcEndPoint = new ArcSegment(outerArcEndPoint, new Size(Radius, Radius), 0, false, SweepDirection.Clockwise, true);
            LineSegment lineToInnerArcEndPoint = new LineSegment(innerArcEndPoint, false);
            ArcSegment arcToinnerAcsStartPoint = new ArcSegment(innerArcStartPoint, new Size(innerRadius, innerRadius), 0, false, SweepDirection.Counterclockwise, true);

            pathFigure.StartPoint = innerArcStartPoint;
            pathFigure.Segments.Add(lineToOuterArcStartPoint);
            pathFigure.Segments.Add(arcToOuterArcEndPoint);
            pathFigure.Segments.Add(lineToInnerArcEndPoint);
            pathFigure.Segments.Add(arcToinnerAcsStartPoint);

            return pathFigure;
        }

        /// <summary>
        /// 把角度转换成幅度坐标,返回的角度是用正上方开始为0度，向右旋转，和数学的不一样
        /// </summary>
        /// <param name="angle">角度</param>
        /// <param name="radius">半径</param>
        /// <returns></returns>
        public Point ComputeCartesianCoodinate(double angel, double radius)
        {
            Point res = new Point();
            //矫正偏移量 转化为 pi的形式
            double angleRad = (Math.PI / 180.0) * (angel - 90);
            // 转化为坐标
            double x = radius * Math.Cos(angleRad);
            double y = radius * Math.Sin(angleRad);
            res = new Point(x, y);
            return res;
        }
    }
}
